package com.an_yang_gang_yie.an_yang_gang_yie.config;

import com.an_yang_gang_yie.an_yang_gang_yie.entity.AjaxResponseBody;
import com.an_yang_gang_yie.an_yang_gang_yie.enum_util.ResponseBodyEnum;
import com.auth0.jwt.exceptions.JWTDecodeException;
import com.auth0.jwt.exceptions.TokenExpiredException;
import org.springframework.dao.QueryTimeoutException;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.validation.BindException;
import org.springframework.validation.ObjectError;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import java.util.List;
import java.util.stream.Collectors;

@RestControllerAdvice
@Component
public class GlobalExceptionHandler {


    /**
     * 数据校验异常借用 JWTDecodeException
     * @param e
     * @return
     */
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ExceptionHandler(JWTDecodeException.class)
    public AjaxResponseBody handler(JWTDecodeException e){
        return AjaxResponseBody.fail(ResponseBodyEnum.RESPONSE_BODY_TOKEN_ERROR.getCode()
                ,e.getMessage(),null);
    }
    /**
     * token过期异常
     * @param e
     * @return
     */
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ExceptionHandler(TokenExpiredException.class)
    public AjaxResponseBody handler(TokenExpiredException e){
        return AjaxResponseBody.fail(ResponseBodyEnum.RESPONSE_BODY_TOKEN_INVALID.getCode(),
                ResponseBodyEnum.RESPONSE_BODY_TOKEN_INVALID.getMsg(),null);
    }

    /**
     * 校验方法是否正确
     * @param e
     * @return
     */
    @ResponseStatus(HttpStatus.METHOD_NOT_ALLOWED)
    @ExceptionHandler(HttpRequestMethodNotSupportedException.class)
    public AjaxResponseBody handler(HttpRequestMethodNotSupportedException e){
        String data = "支持的方法类型是"+e.getSupportedHttpMethods()+"您使用的是方法类型是"+e.getMethod();
        return AjaxResponseBody.fail(data);
    }
    /**
     * 处理实体校验的异常
     * @param e
     * @return
     */
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ResponseBody
//    @ExceptionHandler(MethodArgumentNotValidException.class)
    @ExceptionHandler(value = BindException.class)
    public AjaxResponseBody handler(BindException e) {
        List<ObjectError> allErrors = e.getAllErrors();
        String collect = allErrors.stream().map(ObjectError::getDefaultMessage).collect(Collectors.joining("-"));
        System.out.println(collect);
        return AjaxResponseBody.fail(collect);
    }

    /**
     * 处理Assert的异常NullPointerException
     * @param e
     * @return
     */
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ExceptionHandler(value = IllegalArgumentException.class)
    public AjaxResponseBody handler(IllegalArgumentException e) {
        return AjaxResponseBody.fail(e.getMessage());
    }

    /**
     * 捕捉其他异常 运行异常报错
     * @param e
     * @return
     */
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ExceptionHandler(value = RuntimeException.class)
    public AjaxResponseBody handler(RuntimeException e) {
        System.out.println("1231");
        e.printStackTrace();
        return AjaxResponseBody.fail(e.getMessage());
    }

    /**
     * redis请求超时错误
     * @param e
     * @return
     */
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    @ExceptionHandler(value = QueryTimeoutException.class)
    public AjaxResponseBody handler(QueryTimeoutException e){

        return AjaxResponseBody.fail(ResponseBodyEnum.RESPONSE_BODY_REDIS_TIME_OUT);
    }
}
